package Data::Semantic::Net::IPAddress::IPv4;

use strict;
use warnings;
use Net::IP qw/ip_is_ipv4 ip_iptype ip_iptobin/;


our $VERSION = '0.02';


use base qw(Data::Semantic::Net::IPAddress);


sub is_valid_normalized_value {
    my ($self, $value) = @_;

    # Net::IP has a "nice" DWIM feature which
    # autocompletes IPs with less than 4 octets, so check for that

    $self->SUPER::is_valid_normalized_value($value) && ip_is_ipv4($value)
        && (my @dummy = split(/\./,$value)) == 4;

}

    
sub is_internal {
    my ($self, $value) = @_;
    return unless defined $value;

    # Net::IP::ip_iptype needs the IP in binary, although this is not
    # documented. 

    my $type = ip_iptype(ip_iptobin($value, 4), 4) || 'PUBLIC';
    $type ne 'PUBLIC';
}   


1;


__END__

{% USE p = PodGenerated %}

=head1 NAME

{% p.package %} - semantic data class for IPv4 addresses

=head1 SYNOPSIS

    my $obj = {% p.package %}->new;
    if ($obj->is_valid($value)) { ... }

=head1 DESCRIPTION

This class can tell whether a value is an IPv4 address. The C<valid()> methd
will respect the inherited C<forbid_internal> boolean attribute.

{% p.write_inheritance %}

=head1 METHODS

=over 4

{% p.write_methods %}

=item is_internal

Takes a value and returns true if the indicated IPv4 address is an internal
address (e.g., C<10.0.1.1>, C<127.0.0.1>, C<192.168.1.3>)

=back

{% PROCESS standard_pod %}

=cut

